package erfgame.core.world.terrain.factory;

import erfgame.core.world.terrain.MaterialType;
import erfgame.core.world.terrain.TerrainConstants;
import erfgame.core.world.terrain.TerrainUpdate;
import erfgame.core.world.terrain.TerrainUpdateByMaterialTypeFactory;
import erfgame.core.world.terrain.TerrainUpdateGroup;

public class SphereTerrainUpdateByMaterialTypeFactory 
	implements TerrainUpdateByMaterialTypeFactory {
	
	private int diameter;
	
	public SphereTerrainUpdateByMaterialTypeFactory( int diameter ) {
		this.diameter = diameter;
	}

	public TerrainUpdateGroup createTerrainUpdate(byte materialType) {
		int rx = diameter/2;
		int cx = rx;
		int cy = rx;
		int cz = (int)Math.ceil((((double)diameter) * TerrainConstants.DEPTH_MULTIPLIER)/2D);
		
		int width = diameter;
		int height = diameter;
		int depth = (int)Math.ceil(diameter * TerrainConstants.DEPTH_MULTIPLIER); 
		
		short materialTypeId = (short)(TerrainUpdate.FLAG_FORCE_OVERWRITE | ((byte)materialType));
		short[][][] terrain = new short[width][height][depth+1];
		for( int x=- rx; x<rx; x++ ) {
			int ry = (int)Math.round( Math.sqrt( rx * rx - x * x) );
			for( int y=-ry; y<ry; y++ ) {
				int rz = (int)(Math.round( Math.sqrt( ry * ry - y * y )* TerrainConstants.DEPTH_MULTIPLIER ) );
				for( int z=-rz; z<rz; z++ ) {
					int px = cx + x;
					int py = cy + y;
					int pz = cz + z;
					if( px < width && py < height && pz < depth && px>=0 && py>=0 && pz>=0 ) {
						terrain[px][py][pz] = materialTypeId;
					}
				}
			}
		}		
		 return new TerrainUpdateGroup( new TerrainUpdate( terrain, width, height, depth+1 ) );
	}

}
